
#include "ps2_client.h"
#include <Arduino.h>

#ifndef __ps2_client_kb_H__
#define __ps2_client_kb_H__

// PS2编码表
//  下标：序列号0
//  值：对应的PS/2扫描码
//      0x00：不支持
//      0xE0：扩展码——需要另外查表
const uint8_t PS2_SET2_MAKE[] = {
    0x00, // 00 N/A
    0x1C, // 01 A
    0x32, // 02 B
    0x21, // 03 C
    0x23, // 04 D
    0x24, // 05 E
    0x2B, // 06 F
    0x34, // 07 G
    0x33, // 08 H
    0x43, // 09 I
    0x3B, // 10 J
    0x42, // 11 K
    0x4B, // 12 L
    0x3A, // 13 M
    0x31, // 14 N
    0x44, // 15 O
    0x4D, // 16 P
    0x15, // 17 Q
    0x2D, // 18 R
    0x1B, // 19 S
    0x2C, // 20 T
    0x3C, // 21 U
    0x2A, // 22 V
    0x1D, // 23 W
    0x22, // 24 X
    0x35, // 25 Y
    0x1A, // 26 Z
    0x45, // 27 0
    0x16, // 28 1
    0x1E, // 29 2
    0x26, // 30 3
    0x25, // 31 4
    0x2E, // 32 5
    0x36, // 33 6
    0x3D, // 34 7
    0x3E, // 35 8
    0x46, // 36 9
    0x0E, // 37 ` ~    JPN 半角/全角|汉字
    0x4E, // 38 - _    JPN - =
    0x55, // 39 = +    JPN ^ ~
    0x5D, // 40 \ |
    0x66, // 41 backspace
    0x29, // 42 space
    0x0D, // 43 tab
    0x58, // 44 caps lock
    0x12, // 45 L shift
    0x14, // 46 L ctrl
    0xE0, // 47 L WIN
    0x11, // 48 L Alt
    0x59, // 49 R shift
    0xE0, // 50 R ctrl
    0xE0, // 51 R WIN
    0xE0, // 52 R Alt
    0xE0, // 53 application
    0x5A, // 54 return
    0x76, // 55 Esc
    0x05, // 56 F1
    0x06, // 57 F2
    0x04, // 58 F3
    0x0C, // 59 F4
    0x03, // 60 F5
    0x0B, // 61 F6
    0x83, // 62 F7
    0x0A, // 63 F8
    0x01, // 64 F9
    0x09, // 65 F10
    0x78, // 66 F11
    0x07, // 67 F12
    0xE0, // 68 print screen
    0x7E, // 69 scroll lock
    0xE0, // 70 pause
    0x54, // 71 [ {     JPN @ ·
    0xE0, // 72 insert
    0xE0, // 73 home
    0xE0, // 74 page up
    0xE0, // 75 del
    0xE0, // 76 end
    0xE0, // 77 page down
    0xE0, // 78 up
    0xE0, // 79 left
    0xE0, // 80 down
    0xE0, // 81 right
    0x77, // 82 num lock
    0xE0, // 83 num /
    0x7C, // 84 num *
    0x7B, // 85 num -
    0x79, // 86 num +
    0xE0, // 87 num enter
    0x71, // 88 num . del
    0x70, // 89 num 0
    0x69, // 90 num 1
    0x72, // 91 num 2
    0x7A, // 92 num 3
    0x6B, // 92 num 4
    0x73, // 94 num 5
    0x74, // 95 num 6
    0x6C, // 96 num 7
    0x75, // 97 num 8
    0x7D, // 98 num 9
    0x5B, // 99 ] }      JPN [ {
    0x4C, // 100 ; :     JPN ; +
    0x52, // 101 ' "     JPN : *
    0x41, // 102 , <
    0x49, // 103 . >
    0x4A, // 104 / ?
    0x5D, // 105
    0x51, // 106         JPN \ -
    0x13, // 107         JPN 输入方式变换
    0x6A, // 108         JPN 羊 |
    0x64, // 109         JPN 变换
    0x67, // 110         JPN 无变换
    0x00, // 111 N/A
    0x00, // 112 N/A
    0x00, // 113 N/A
    0x00, // 114 N/A
    0x00, // 115 N/A
    0x00, // 116 N/A
    0x00, // 117 N/A
    0x00, // 118 N/A
    0x00, // 119 N/A
    0xE0, // 120 power
};

// 机打速率表 (ms)
const unsigned short PS2_KeyRepeatRate[] = {
    500, // 0x00  2.0cps
    476, // 0x01  2.1cps
    434, // 0x02  2.3cps
    400, // 0x03  2.5cps
    370, // 0x04  2.7cps
    333, // 0x05  3.0cps
    303, // 0x06  3.3cps
    270, // 0x07  3.7cps
    250, // 0x08  4.0cps
    232, // 0x09  4.3cps
    217, // 0x0A  4.6cps
    200, // 0x0B  5.0cps
    181, // 0x0C  5.5cps
    166, // 0x0D  6.0cps
    149, // 0x0E  6.7cps
    133, // 0x0F  7.5cps
    125, // 0x10  8.0cps
    116, // 0x11  8.6cps
    108, // 0x12  9.2cps
    100, // 0x13  10.0cps
    91,  // 0x14  10.9cps
    83,  // 0x15  12.0cps
    75,  // 0x16  13.3cps
    66,  // 0x17  15.0cps
    62,  // 0x18  16.0cps
    58,  // 0x19  17.1cps
    54,  // 0x1A  18.5cps
    50,  // 0x1B  20.0cps
    45,  // 0x1C  21.8cps
    41,  // 0x1D  24.0cps
    37,  // 0x1E  26.7cps
    33   // 0x1F  30.0cps
};

// 机打延时表 (ms)
const unsigned short PS2_KeyDelay[] = {
    250, // 0x00  250ms
    500, // 0x01  500ms
    750, // 0x02  750ms
    1000 // 0x03  1000ms
};

typedef struct PS2_KB_INFO {
    uint8_t STATUS;           // 0x0: 未初始化； 0x01: 可用
    uint8_t LED;              // 0x04: Caps Lock;  0x02: Num Lock;  0x01:Scroll Lock
    uint8_t Enable;           // 0: 停止扫描  1: 使能
    bool firstKeyRepeat;      // 机打第一帧
    uint16_t KeyRepeat;       // 机打按键 —— 将对此按键进行重复发送
    uint16_t KeyRepeatRate;   // 机打频率 —— 换算成ms计数
    uint16_t KeyDelay;        // 机打延时 —— 换算成ms计数
    u_long KeyDelayTime;      // 机打延时计时
    uint8_t Keymode[120];     // 每个按键的发送方法       // 0：默认，0x01:禁止断码, 0x02:禁止机打
} _PS2_KB_INFO;

class PS2_Client_KB_Callbacks {
public:
    virtual void ps2kb_setLED(uint8_t param) { ; }
};

class PS2_Client_KB : public PS2_Client {
private:
    PS2_Client_KB_Callbacks *_pCallbacks = nullptr; // 事件通知对象
    void copy_code(uint8_t index, uint8_t type);

public:
    PS2_KB_INFO _PS2_KB_INFO;

    void makeData();
    void readAndExec();
    void resetDevice();

    void setKey(int key, int status); // 设置按键状态（0：释放 1:按下）

    void setEventCallbacks(PS2_Client_KB_Callbacks *);
};

#endif
